package main

import (
	"crypto/tls"
	"crypto/x509"
	"flag"
	"io/ioutil"
	"net"
	"os"
	"os/signal"
	"syscall"

	"github.com/golang/glog"

	"gitee.com/jason_elva8325/go-utils/etcdv3"

	"gitee.com/jason_elva8325/go-utils/examples/etcdv3/pb"

	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

var svcName = "project/test"
var svcAddr = "127.0.0.1:50051"
var etcdAddr = "127.0.0.1:2379"

func main() {
	flag.StringVar(&svcName, "svcName", svcName, "svcName")
	flag.StringVar(&svcAddr, "svcAddr", svcAddr, "svcAddr to lis")
	flag.StringVar(&etcdAddr, "etcdAddr", etcdAddr, "etcdAddr to reg")
	flag.Parse()

	lis, err := net.Listen("tcp", svcAddr)
	if err != nil {
		glog.Fatalf("failed to listen: %s", err)
	}
	defer lis.Close()

	s := grpc.NewServer()
	defer s.GracefulStop()

	pb.RegisterHelloServiceServer(s, &hello{})

	// load cert
	cert, err := tls.LoadX509KeyPair("/tmp/client.pem", "/tmp/client-key.pem")
	if err != nil {
		glog.Fatal(err)
	}

	// load root ca
	caData, err := ioutil.ReadFile("/tmp/ca.pem")
	if err != nil {
		glog.Fatal(err)
	}

	pool := x509.NewCertPool()
	pool.AppendCertsFromPEM(caData)

	go func() {
		err := etcdv3.Register(etcdAddr, svcName, svcAddr, 5, &tls.Config{
			Certificates: []tls.Certificate{cert},
			RootCAs:      pool,
		})
		if err != nil {
			glog.Errorf("etcdv3 regist fail: %v", err)
		}
		glog.Infoln("etcdv3 regist success")
	}()

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGQUIT)
	go func() {
		s := <-ch
		etcdv3.UnRegister(svcName, svcAddr)

		if i, ok := s.(syscall.Signal); ok {
			os.Exit(int(i))
		} else {
			os.Exit(0)
		}

	}()

	if err := s.Serve(lis); err != nil {
		glog.Fatalf("failed to serve: %s", err)
	}
}

type hello struct {
}

func (*hello) Echo(ctx context.Context, req *pb.Payload) (*pb.Payload, error) {
	req.Data = req.Data + ", from:" + svcAddr
	return req, nil
}
